﻿using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Linq;
using System.Linq.Expressions;

namespace SoftSource.Common
{
    public static class NotificationExtensions
    {
        /// <summary>
        /// Converts PropertyChanged events into an IObservable notification stream.
        /// </summary>
        /// <param name="notifier">An object that impliments INotifyPropertyChanged</param>
        /// <returns>An Observable event stream of property changed notifications</returns>
        public static IObservable<IEvent<PropertyChangedEventArgs>> WhenPropertyChanged(this INotifyPropertyChanged notifier)
        {
            return Observable.FromEvent<PropertyChangedEventHandler, PropertyChangedEventArgs>(
                handler => (sender2, e2) => handler(sender2, e2),
                handler => notifier.PropertyChanged += handler,
                handler => notifier.PropertyChanged -= handler);
        }

        public static IObservable<IEvent<NotifyCollectionChangedEventArgs>> WhenCollectionChanged(this INotifyCollectionChanged notifier)
        {
            return Observable.FromEvent<NotifyCollectionChangedEventHandler, NotifyCollectionChangedEventArgs>(
                handler => (sender2, e2) => handler(sender2, e2),
                handler => notifier.CollectionChanged += handler,
                handler => notifier.CollectionChanged -= handler);
        }

        public static void Notify(this PropertyChangedEventHandler handler, Expression<Func<object>> propertyExpression)
        {
            if (handler != null)
            {
                string propertyName = ObjectReflection.GetPropertyName(propertyExpression);
                handler(null, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
}
